package com.zero.rpc.core.proxy;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.zero.rpc.core.RpcApplication;
import com.zero.rpc.core.config.RpcConfig;
import com.zero.rpc.core.constant.RpcConstant;
import com.zero.rpc.core.model.RpcRequest;
import com.zero.rpc.core.model.RpcResponse;
import com.zero.rpc.core.model.ServiceMetaInfo;
import com.zero.rpc.core.serializer.JdkSerializer;
import com.zero.rpc.core.serializer.Serializer;
import com.zero.rpc.core.serializer.SerializerFactory;
import com.zero.rpc.core.utils.ConfigUtils;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ServiceLoader;

/**
 *
 * 一个代理 用来对 封装请求，进行代理
 * */
public class ServiceProxy implements InvocationHandler {

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //  指定序列化器
        // 指定序列化器
        final Serializer serializer = SerializerFactory.getInstance(RpcApplication.getRpcConfig().getSerializer());

        // 构造请求
        String serviceName = method.getDeclaringClass().getName();
        // 构建请求
        RpcRequest args1 = RpcRequest.builder()
                .serviceName(method.getDeclaringClass().getName())
                .methodName(method.getName())
                .parameterTypes(method.getParameterTypes())
                .args(args).build();

        // 请求序列化
        byte[] bodyBytes = serializer.serialize(args1);


        RpcConfig rpcConfig = RpcApplication.getRpcConfig();
//
//        RpcConfig rpcConfig = ConfigUtils.loadConfig(RpcConfig.class, RpcConstant.DEFAULT_CONFIG_PREFIX);
        // 发送请求
        try(HttpResponse httpResponse = HttpRequest.post("http://"+rpcConfig.getServerHost()+":"+rpcConfig.getServerPort())
                .body(bodyBytes)
                .execute()){
            byte[] results = httpResponse.bodyBytes();
            // 反序列化
            RpcResponse rpcResponse = serializer.deserialize(results, RpcResponse.class);
            return rpcResponse.getData();
        }catch (Exception e){
           e.printStackTrace();
        }


        return null;
    }
}
